#ifndef MEMHASHED_STRING_PIECE_H_
#define MEMHASHED_STRING_PIECE_H_

#include <stdint.h>
#include <string.h>
#include <string>
#include "log.h"

namespace memhashed {

class StringPiece {

    public:
        typedef char * iterator;
        typedef const char * const_iterator;
        typedef char value_type;
        typedef size_t size_type;

        StringPiece() : m_ptr(NULL), m_length(0) {}
        StringPiece(const std::string &stdstr) : m_ptr(stdstr.c_str()), 
        m_length(stdstr.size()) {
        }
        StringPiece(const char *p) : m_ptr(p), m_length(strlen(p)) {}
        StringPiece(const char *p, StringPiece::size_type length) {
            xassert(length >= 0);
            m_ptr = p;
            size_t len = strlen(p);
            m_length = length > len ? len : length; 
        }

        StringPiece(const StringPiece &other) {
            m_ptr = other.Data(); 
            m_length = other.Length();
        }
        StringPiece &operator=(const StringPiece &other) {
            if (this == &other) return *this;
            m_ptr = other.Data();
            m_length = other.Length();
            return *this;
        }

    public:
        uint32_t Length() const { return m_length; } 
        bool Empty() const { return m_length == 0; }
        void Clear() { m_ptr = NULL; m_length = 0; }
        void Set(char *p, uint32_t len) { 
            m_ptr = p;
            m_length = len;
        }
        void Set(const std::string &stdstr) {
            m_ptr = stdstr.c_str();
            m_length = stdstr.size();
        }
        void Set(const char *p) {
            m_ptr = p;
            m_length = strlen(p);
        }

        StringPiece::value_type operator[](int i) const {
            xassert(i < m_length);
            return m_ptr[i];
        }

        const_iterator   Data() const { return m_ptr; }

        bool operator==(const char *str) {
            return !strcmp(str, m_ptr) ? true : false;
        }
        bool operator==(const char *str, size_t len) {
            if (len != m_length) return false;
            return !strncmp(str, m_ptr, len) ? true : false;
        }
        bool operator==(const std::string &str) {
            if (str.size() != m_lenth) return false;
            return !strcmp(str.c_str(), m_ptr) ? true : false;
        }

    private:
        const char *m_ptr;
        uint32_t    m_length;        
};
}
#endif
